package com.rm.vip;

import com.rm.vip.request.RequestData;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
import java.net.Socket;

/**
 * @ProjectName: vip-rpc-parent
 * @Auther: GERRY
 * @Date: 2019/1/15 21:30
 * @Description:
 */
public class RpcClient {
    public static <T> T getRemoteProxy(Class<T> interfaceCls, InetSocketAddress address) {
        return (T) Proxy.newProxyInstance(interfaceCls.getClassLoader(),
                new Class<?>[]{interfaceCls},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 1、通过ip和端口实现网络连接
                        // 2、把调用服务端需要参数发送到服务端
                        // 3、获取服务端调用返回的结果
                        try (Socket socket = new Socket()){
                            socket.connect(address);

                            try (
                                    ObjectOutputStream serializer = new ObjectOutputStream(socket.getOutputStream());
                                    ObjectInputStream deSerializer = new ObjectInputStream(socket.getInputStream())
                            ){
                                // 封装一个发送的服务端的对象
                                RequestData data = new RequestData();
                                data.setInterfaceName(interfaceCls.getName());
                                data.setMethodName(method.getName());
                                data.setParameters(args);
                                data.setParameterTypes(method.getParameterTypes());
                                serializer.writeObject(data);

                                // 反序列化结果
                                return deSerializer.readObject();

                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }

                        return null;
                    }
                });
    }
}
